<template>
  <div style="display: flex">
    <div class="tab">
      <div
        class="tab-item"
        :class="{ active: tabActive == 'Map' }"
        @click="tabActive = 'Map'"
      >
        Map
      </div>
      <div
        class="tab-item"
        :class="{ active: tabActive == 'Diagram' }"
        @click="tabActive = 'Diagram'"
      >
        Diagram
      </div>
    </div>
    <div id="cesium-container" v-show="tabActive == 'Map'"></div>
    <div v-show="tabActive == 'Diagram'"></div>
    <div class="left-side" v-show="expand">
      <div class="tab">
        <div
          class="tab-item"
          :class="{ active: subTabActive == 'RWPS' }"
          @click="subTabActive = 'RWPS'"
        >
          RWPS
        </div>
        <div
          class="tab-item"
          :class="{ active: subTabActive == 'WTW' }"
          @click="subTabActive = 'WTW'"
        >
          WTW
        </div>
        <div
          class="tab-item"
          :class="{ active: subTabActive == 'Res.' }"
          @click="subTabActive = 'Res.'"
        >
          Res.
        </div>
      </div>
    </div>
    <div class="arrow">
      <div
        class="arrow-left arrow-item"
        v-show="expand"
        @click="expand = false"
      >
        &lt;
      </div>
      <div
        class="arrow-right arrow-item"
        v-show="!expand"
        @click="expand = true"
      >
        &gt;
      </div>
    </div>
    <div class="right-side">
      <div class="component">
        <div class="component-item">{{ date }}</div>
        <div class="component-item"></div>
      </div>
      <div class="content-item">
        <div class="title">
          <div class="info">DJ water import amount</div>
          <div class="select" style="width: 50px">
            <el-select v-model="DJValue" size="small">
              <el-option
                v-for="item in DJOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
        </div>
      </div>
      <div class="content-item">
        <div class="title">
          <div class="info">RWPS Consumption & Efficiency</div>
          <div class="select" style="width: 80px">
            <el-select v-model="RWPSValue" size="small">
              <el-option
                v-for="item in RWPSOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
        </div>
      </div>
      <div class="content-item">
        <div class="title">
          <div class="info">Pumps Operation & Priority</div>
          <div class="select" style="width: 80px">
            <el-select v-model="PumpsValue" size="small">
              <el-option
                v-for="item in PumpsOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script name="Index" setup>
import * as Cesium from "cesium";
import { ref, computed, onMounted, reactive } from "vue";
import data from "../assets/data/taipo";
import {
  getIndex,
  getColors,
  getHeights,
  handleSortArr,
  handleSortList,
  handleDegreesArrayHeights,
} from "./map";

Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZTgxOGNhZC03NThmLTQ0NzMtOTNlYS1kNmM3YzlmZDU3NTMiLCJpZCI6MTI1NTY3LCJpYXQiOjE2NzY5MDI0MzJ9.ulIEz3NCh2cMEBiHrqIuv9I6icn5KTMMnBdy2wassoM";

let viewer, handler, points, lines;
let glopri;
let pre_listen;

let dateInterval;
const date = ref(null);
const tabActive = ref("Map");
const subTabActive = ref("RWPS");
const expand = ref(true);
const DJValue = ref(undefined);
const DJOptions = ref([
  {
    value: "daily",
    label: "日",
  },
  {
    value: "monthly",
    label: "月",
  },
  {
    value: "annually",
    label: "年",
  },
]);
const RWPSValue = ref(undefined);
const RWPSOptions = ref([
  {
    value: "2023-06-05",
    label: "2023-06-05",
  },
  {
    value: "2023-07-05",
    label: "2023-07-05",
  },
]);
const PumpsValue = ref(undefined);
const PumpsOptions = ref([
  {
    value: "Muk Wu No.2",
    label: "Muk Wu No.2",
  },
  {
    value: "Muk Wu No.3",
    label: "Muk Wu No.3",
  },
]);

// 添加地图
const initMap = () => {
  viewer = new Cesium.Viewer("cesium-container", {
    infoBox: false, // 信息框
    timeline: false, // 时间轴小部件
    homeButton: false, // 定位到地球视角按钮
    baseLayerPicker: false, // 选择底图按钮
    navigationHelpButton: false, // 帮助按钮
    animation: false, // 动画小部件
    sceneModePicker: false, // 切换2D/3D按钮
    fullscreenButton: false, // 全屏按钮
  });
  // 去掉logo
  viewer.cesiumWidget.creditContainer.style.display = "none";
};
// 添加点击事件
const addHandler = () => {
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction((movement) => {
    let pick = viewer.scene.pick(movement.position);
    console.log(pick);
    if (!pick) return;
    if (pick.id.name == "point") {
      const attributes = pick.primitive.getGeometryInstanceAttributes(pick.id);
      attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
        Cesium.Color.YELLOW
      );
    } else if (pick.id.name == "line") {
      // const attributes = pick.primitive.getGeometryInstanceAttributes(pick.id);
      // console.log(attributes)
      // attributes.color =Cesium.Color.YELLOW;
      if (glopri) {
        viewer.scene.primitives.remove(glopri);
        //glopri = undefined;
        //viewer.scene.preRender.removeEventListener(pre_listen);
        addLinesPrimitives(pick.id.id);
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
// 添加点
const addPointsPrimitives = () => {
  // 点
  const length = data.junction_id.length;
  const pointsGeometry = [];
  for (let index = 0; index <= length - 1; index++) {
    pointsGeometry.push(
      new Cesium.GeometryInstance({
        geometry: new Cesium.CircleGeometry({
          center: Cesium.Cartesian3.fromDegrees(
            data.junction_y[index],
            data.junction_x[index]
          ),
          height: data.junction_elev[index],
          radius: 2,
        }),
        id: { id: data.junction_id[index], name: "point" },
        attributes: {
          color: new Cesium.ColorGeometryInstanceAttribute(
            7 / 255,
            213 / 255,
            11 / 255,
            1
          ),
        },
      })
    );
  }

  viewer.scene.primitives.add(
    new Cesium.Primitive({
      geometryInstances: pointsGeometry,
      releaseGeometryInstances: false,
      appearance: new Cesium.PerInstanceColorAppearance({
        flat: true,
        translucent: false,
      }),
    })
  );
};
// 添加线
const addLinesPrimitives = (pid) => {
  // 线
  const linesGeometry = [];
  const length = data.pipe_id.length;
  for (let index = 0; index <= length - 1; index++) {
    // heights不用使用handleSortArr方法排序，因为是通过pipe_startNode和pipe_endNode获取的，已经排好顺序
    let heights = getHeights(
      data.junction_elev[
        getIndex(data.pipe_startNode[index], data.junction_id)
      ],
      data.junction_elev[getIndex(data.pipe_endNode[index], data.junction_id)],
      data.pipe_vertices[index]
    );
    let geid = data.pipe_id[index];
    let usesingel;
    if (pid === geid) {
      usesingel = true;
    }
    let colors = getColors(
      handleSortArr(data.pipe_vertices[index], data.pipe_flow[index]),
      data.pipe_length[index],
      usesingel
    );
    linesGeometry.push(
      new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          positions: Cesium.Cartesian3.fromDegreesArrayHeights(
            handleDegreesArrayHeights(
              handleSortArr(data.pipe_vertices[index], data.pipe_flow[index]),
              heights,
              data.pipe_flow[index]
            )
          ),
          width: 2,
          colors: colors,
          colorsPerVertex: true,
          vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT,
        }),
        id: { id: geid, name: "line" },
        // attributes: {
        // 	color: new Cesium.ColorGeometryInstanceAttribute(3 / 255, 241 / 255, 242 / 255, 1)
        // }
        // attributes: {
        // 	color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(3 / 255, 241 / 255, 242 / 255, 1))
        // },
      })
    );
  }
  let material = new Cesium.Material({
    fabric: {
      uniforms: {
        u_itime: 10.0,
        u_trailpercent: 0.3,
        u_trailmovespeed: 5.0 / 50.0,
      },
    },
  });
  let primitive = new Cesium.Primitive({
    asynchronous: false,
    geometryInstances: linesGeometry,
    releaseGeometryInstances: false,
    appearance: new Cesium.PolylineColorAppearance({
      translucent: false,
      fragmentShaderSource: `precision highp float;
				  in vec4 v_color;
				  void main() {
					  float rate = 1000.0;
					  float length = v_color.r*rate;
					  float total_length = v_color.g*rate;
					  float render_time = 5.0;
					  float total_time = 10.0;
					  float r = length - mod(u_itime_0,total_time)*total_length/render_time;
					  float dist = smoothstep(total_time,render_time,mod(u_itime_0,total_time));
					  if(dist == 1.0){
						  if(r > 0.0){
							dist = 0.0;
						  }
					  }
					  out_FragColor = vec4(1.0, 0.0, 0.0, dist);
				  }`,
    }),
  });
  primitive.appearance.material = material;
  viewer.scene.primitives.add(primitive);
  glopri = primitive;

  pre_listen = function (s, t) {
    let elaspTime = Cesium.JulianDate.now().secondsOfDay - t.secondsOfDay;
    if (glopri) glopri.appearance.material.uniforms.u_itime = elaspTime;
  };

  viewer.scene.preRender.addEventListener(pre_listen);
};
// 定位
const setView = (x, y, z) => {
  if (x instanceof Array || y instanceof Array) {
    // 如果x和y是数组，根据x和y计算出定位的矩形范围
    viewer.camera.setView({
      destination: Cesium.Rectangle.fromDegrees(...handleData(x, y)),
      duration: 0,
      complete: () => {},
    });
  } else {
    viewer.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(x, y, z),
      duration: 0,
      complete: () => {},
    });
  }

  function handleData(x_arr, y_arr) {
    var xmax = 0;
    var xmin = 180;
    var ymax = 0;
    var ymin = 90;
    x_arr.forEach((x) => {
      xmax = Math.max(xmax, x);
      xmin = Math.min(xmin, x);
    });
    y_arr.forEach((y) => {
      ymax = Math.max(ymax, y);
      ymin = Math.min(ymin, y);
    });
    var shift_x = (xmax - xmin) / 20;
    var shift_y = (ymax - ymin) / 20;
    return [xmin - shift_x, ymin - shift_y, xmax + shift_x, ymax + shift_y];
  }
};
// 获取时间
function getDate() {
  if (dateInterval) clearInterval(dateInterval);
  dateInterval = setInterval(() => {
    date.value = formatDateByProp(new Date(), "yyyy-MM-dd hh:mm:ss");
  }, 1000);
}

onMounted(() => {
  initMap();
  addHandler();
  addPointsPrimitives();
  addLinesPrimitives();
  setView(data.junction_y, data.junction_x);
  getDate();
});
</script>

<style scoped>
#cesium-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>
